﻿using Newtonsoft.Json;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Zocono.Infrastructure.Common;
using Zocono.WCS.Domain.DomainRepository;
using Zocono.WCS.Domain.EntityInfo;
using Zocono.WCS.Domain.LogDomain;
using Zocono.WCS.Domain.PlcBytesObject;
using Zocono.WCS.Domain.PlcConnectPoolDomain;
using Zocono.WCS.Domain.ProcessModuleDomain;
using Zocono.WCS.Infrastructure.ApllicationDto.DtoWcsManage;
using Zocono.WCS.Infrastructure.ApllicationDto.Enums;
using Zocono.WCS.Infrastructure.ApllicationDto.WCSTaskDto;
using Zocono.WCS.Infrastructure.PlcCommon;
using Zocono.WCS.WMSApiDomain.WebApi;
using PlanarGeneralPlcActionBO = Zocono.WCS.Domain.PlcBytesObject.PlanarGeneralPlcActionBO;
using PlanarGeneralWcsActionBO = Zocono.WCS.Domain.PlcBytesObject.PlanarGeneralWcsActionBO;

namespace Zocono.WCS.Domain.EquipmentProcessDomain.PlanarGeneralMessage
{
    public class ScanBandingService : IPlanarGeneralPlcActionProcessService
    {
        private readonly IRedisHelper _IRedisHelper;
        private readonly ILogUtil _logUtil;
        private readonly ISnowflake _snowflake;
        private readonly IPlcConnectionPool _plcConnectionPool;
        private readonly IWorkTaskInfoRepository _workTaskInfoRepository;
        private readonly IPlcWriteDbInfoRepository _plcWriteDbInfoRepository;
        private readonly IPlcConnectionInfoRepository _PlcConnectionInfoRepository;
        private readonly IPlcPointInfoRepositpry _IPlcPointInfoRepositpry;
        private readonly IPlcConnectionStateInfoRepository _IPlcConnectionStateInfoRepository;
        private readonly IRunLogInfoService _IRunLogInfoService;
        private readonly IPlcReadDbInfoRepository _PlcReadeDbInfoRepository;
        public ScanBandingService(IRedisHelper iRedisHelper, ILogUtil logUtil, ISnowflake snowflake,
            IPlcConnectionPool plcConnectionPool, IWorkTaskInfoRepository workTaskInfoRepository
            , IPlcWriteDbInfoRepository plcWriteDbInfoRepository
            , IPlcPointInfoRepositpry plcPointInfoRepositpry
             , IPlcConnectionInfoRepository plcConnectionInfoRepository
           , IPlcConnectionStateInfoRepository plcConnectionStateInfoRepository
            , IRunLogInfoService runLogInfoService, IPlcReadDbInfoRepository plcReadDbInfoRepository)
        {
            _IRedisHelper = iRedisHelper;
            _logUtil = logUtil;
            _snowflake = snowflake;
            _plcConnectionPool = plcConnectionPool;
            _workTaskInfoRepository = workTaskInfoRepository;
            _plcWriteDbInfoRepository = plcWriteDbInfoRepository;
            _PlcConnectionInfoRepository = plcConnectionInfoRepository;
            _IPlcPointInfoRepositpry = plcPointInfoRepositpry;
            _IPlcConnectionStateInfoRepository = plcConnectionStateInfoRepository;
            _IRunLogInfoService = runLogInfoService;
            _PlcReadeDbInfoRepository = plcReadDbInfoRepository;
        }
        public async Task ProcessActionMessageAsync(BytesObjectBase plcActionMessage, BytesObjectBase wcsActionMessage, EquipmentDbObject planarEquipmentDbObject)
        {


            var plcMessage = plcActionMessage as PlanarGeneralPlcActionBO;//Plc的动作报文
            var wcsMessage = wcsActionMessage as PlanarGeneralWcsActionBO;//Wcs的动作报文
            plcMessage.PalletBarcode = plcMessage.PalletBarcode.Trim();

            RunLogInfo runLogInfo = new();
            runLogInfo.ContainerBarcode = plcMessage.PalletBarcode;
            runLogInfo.EquipmentCode = plcMessage.EquipmentCode;
            runLogInfo.RunType = "扫码绑盘机";

            //var plcStateBo = plcStateMassge as PlcOnLineStateBO;//Plc在线离线报文 没有设备信息
            PlanarGeneralWriteWcsAction writeBo = null;//写入Plc的报文
            PlcConnectionS7 plcConn = _plcConnectionPool.S7GetWritePlcConnection(plcMessage.PlcConnectionID);//plc写入连接（不锁定）

            if (plcConn == null)
            {
                //runLogInfo.RunLog = $"获取连接({writeBo.PlcConnectionID})失败";
                //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                _logUtil.Error($"扫码绑盘机：托盘【{plcMessage.PalletBarcode}】在设备【{plcMessage.EquipmentCode}】扫码绑盘机检测：plc连接池无数据");
                return;
            }

            runLogInfo.RunLog = "任务开始：扫码绑盘机任务开始";
            //1. 验证plc是否在线
            var plcIPStates = await _IPlcConnectionStateInfoRepository.GetFirstAsync(l => l.PlcConnectionID == plcMessage.PlcConnectionID && l.Connected == true);
            if (plcIPStates == null)
            {
                //runLogInfo.RunLog = $"离线：扫码绑盘机：{plcConn.IP}:plc已离线";
                //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                _logUtil.Error($"扫码绑盘机：托盘【{plcMessage.PalletBarcode}】在设备【{plcMessage.EquipmentCode}】扫码绑盘机检测：请求分配失败：{plcConn.IP}:plc已离线");
                return;
            }

            //if (plcMessage.AlrmCode != 0)
            //{

            //    runLogInfo.RunLog = $"报警：扫码绑盘机：报警代码：{plcMessage.AlrmCode}";
            //    await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
            //    return;
            //}

            //Plc连接Id
            long plcId = wcsMessage.PlcConnectionID;
            //写入plc的报文配置获取
            var objectType = typeof(PlanarGeneralWriteWcsAction).Name;
            var writeConfig = await _plcWriteDbInfoRepository.GetFirstAsync(s => s.EquipmentCode == plcMessage.EquipmentCode && s.ObjectType == objectType);
            if (writeConfig == null)
            {

                //runLogInfo.RunLog = "获取PLC写入配置失败";
                //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                _logUtil.Error($"扫码绑盘机：托盘【{plcMessage.PalletBarcode}】在设备【{plcMessage.EquipmentCode}】扫码绑盘机检测获取PLC写入配置失败！请检查写DB配置！");
                return;
            }
            //校验plc信息是否有托盘码
            if (string.IsNullOrEmpty(plcMessage.PalletBarcode) || plcMessage.PalletBarcode.Length != 10)
            {
                writeBo.AlrmCode = 102;
                writeBo.ActionType = 99;
                var flag = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());
                _IRedisHelper.SetStringKey($"PLC-{plcMessage.EquipmentCode}", plcMessage.EquipmentCode.ToString() + plcMessage.AlrmCode, TimeSpan.FromSeconds(10));
                return;
            }


            //构建写入报文
            writeBo = new PlanarGeneralWriteWcsAction(
                writeConfig.PlcConnectionId,
                writeConfig.ID,
                writeConfig.DbCode,
                writeConfig.DbStart,
                objectType,
                plcMessage.EquipmentCode.ToInt32(),
                //Convert.ToInt32(writeConfig.EquipmentCode),
                plcMessage.ActionType,
                plcMessage.ToEquipmentCode,
                taskCode: plcMessage.TaskCode,
                palletBarcode: plcMessage.PalletBarcode,
                plcMessage.PalletType,
                0);
            //托盘类型
            switch (writeBo.PalletBarcode.Substring(1, 1))
            {
                case "A":
                    writeBo.PalletType = 2;
                    break;
                case "B":
                    writeBo.PalletType = 1;
                    break;
                case "C":
                    writeBo.PalletType = 3;
                    break;
            }

            //if (plcConn == null)
            //{
            //    runLogInfo.RunLog = $"获取连接({writeBo.PlcConnectionID})失败";
            //    await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
            //    return;
            //}

            if (plcMessage.ActionType == 40)
            {
                WCSQueryCombinePalletDto palletDto = new()
                {
                    PalletCode = plcMessage.PalletBarcode,
                };
                var bo = await WCSMessageWithWMSApi.WCSGetBatteryInfoByContainerCodeAsync(palletDto);
                if (bo.IsSucceed&& bo.Result!=null)
                {
                    runLogInfo.RunLog = $"绑盘机获取电池数量成功";
                    writeBo.ActionType = 41;
                    BatteryCountAndTypeDto batteryCountAndTypeInfoDto = bo.Result;
                    writeBo.Reserve3 = batteryCountAndTypeInfoDto.BatteryNum.ToByte();
                    writeBo.Reserve4 = batteryCountAndTypeInfoDto.BatteryAh.ToByte();
                    var writeBl = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());
                    if (!writeBl)
                    {
                        _logUtil.Error($"绑盘机获取电池数量：托盘【{plcMessage.PalletBarcode}】绑盘机获取电池数量成功，PLC设备【{plcMessage.EquipmentCode}】写入PLC失败！");
                    }
                    else
                    {
                        runLogInfo.RunLog = $"绑盘机获取电池数量：托盘【{plcMessage.PalletBarcode}】绑盘机获取电池数量成功，PLC设备【{plcMessage.EquipmentCode}】写入PLC成功！写入报文内容：{JsonConvert.SerializeObject(writeBo)}";
                        await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                        _IRedisHelper.SetStringKey($"PLC-{plcMessage.EquipmentCode}", plcMessage.EquipmentCode.ToString() + plcMessage.AlrmCode, TimeSpan.FromSeconds(10));
                    }
                }
                else
                {
                    //runLogInfo.RunLog = $"绑盘机获取失败,返回信息：{bo.Message}";
                    writeBo.AlrmCode = 126;
                    writeBo.ActionType = 99;
                    var writeBl = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());
                    if (!writeBl)
                    {
                        _logUtil.Error($"绑盘机获取电池数量：托盘【{plcMessage.PalletBarcode}】绑盘机获取失败,返回信息：{bo.Message}，PLC设备【{plcMessage.EquipmentCode}】写入PLC失败！");
                    }
                    else
                    {
                        runLogInfo.RunLog = $"绑盘机获取电池数量：托盘【{plcMessage.PalletBarcode}】绑盘机获取失败,返回信息：{bo.Message}，PLC设备【{plcMessage.EquipmentCode}】写入PLC成功！写入报文内容：{JsonConvert.SerializeObject(writeBo)}";
                        //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                        _logUtil.Error(runLogInfo.RunLog);
                        _IRedisHelper.SetStringKey($"PLC-{plcMessage.EquipmentCode}", plcMessage.EquipmentCode.ToString() + plcMessage.AlrmCode, TimeSpan.FromSeconds(10));
                    }
                }

                return;
            }

            //校验条码
            if (plcMessage.ActionType == 5)
            {
                var plcConfigput = await _PlcReadeDbInfoRepository.GetFirstAsync(l => l.EquipmentCode == plcMessage.EquipmentCode && l.DbCode == 102);


                byte[] bytes = await plcConn.ReadDbAsync(plcConfigput.DbCode, plcConfigput.DbStart, plcConfigput.DbLength);
                if (bytes == null)
                {
                    //runLogInfo.RunLog = $"读DB失败";
                    //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                    _logUtil.Error($"绑盘机获取电池：绑盘机获取电池，PLC设备【{plcMessage.EquipmentCode}】读取DB获取电芯条码失败！");
                    return;
                }

                PlanarBatteryScanPlcActionBO plcActionBO = new();
                plcActionBO.Serialize(plcConfigput.PlcConnectionID, plcConfigput.ID, plcConfigput.DbStart, plcConfigput.DbLength, plcConfigput.DbStart, plcConfigput.DbLength, "PlanarBatteryScanPlcActionBO", plcConfigput.EquipmentCode, bytes);//主要是bytes转化成明文

                WCSCombinePalletInfoDto wCSCombinePalletInfoDto = new()
                {
                    ContainerBarcode = plcMessage.PalletBarcode,
                    EquipmentCode = plcMessage.EquipmentCode
                };

                wCSCombinePalletInfoDto.oneBatteryInfoDtos = GetBatteryDto(plcActionBO);
                //组盘提交数据到WMS
                try
                {
                    var bo = await WCSMessageWithWMSApi.WCSAddComPalletAsync(wCSCombinePalletInfoDto);
                    if (bo)
                    {
                        writeBo.ActionType = 6;
                        runLogInfo.RunLog = $"绑盘校验成功";
                        //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                        _logUtil.Info(runLogInfo.RunLog);
                    }
                    else
                    {
                        writeBo.ActionType = 7;
                        var res = await plcConn.WriteDbAsync(writeConfig.DbCode, writeConfig.DbStart, writeBo.Deserialize());
                        if (res)
                        {
                            runLogInfo.RunLog = $"绑盘机校验：托盘【{plcMessage.PalletBarcode}】绑盘机校验电芯失败，PLC设备【{plcMessage.EquipmentCode}】写入PLC成功！写入报文：{JsonConvert.SerializeObject(writeBo)}";
                            await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                        }
                        else
                        {
                            //runLogInfo.RunLog = $"电池条码为空或位置信息为写入报文失败";
                            //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            _logUtil.Error($"绑盘机校验：托盘【{plcMessage.PalletBarcode}】绑盘机校验电芯失败，PLC设备【{plcMessage.EquipmentCode}】写入PLC失败！");
                        }
                        return;
                    }


                }
                catch (Exception ex)
                {
                    writeBo.ActionType = 7;
                    var res = await plcConn.WriteDbAsync(writeConfig.DbCode, writeConfig.DbStart, writeBo.Deserialize());
                    if (res)
                    {
                        runLogInfo.RunLog = $"绑盘机校验：托盘【{plcMessage.PalletBarcode}】绑盘机校验电芯报错，{ex.Message}，PLC设备【{plcMessage.EquipmentCode}】写入PLC成功！写入报文：{JsonConvert.SerializeObject(writeBo)}";
                        await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                    }
                    else
                    {
                        //runLogInfo.RunLog = $"电池条码为空或位置信息为写入报文失败";
                        //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                        _logUtil.Error($"绑盘机校验：托盘【{plcMessage.PalletBarcode}】绑盘机校验电芯报错，{ex.Message}，PLC设备【{plcMessage.EquipmentCode}】写入PLC失败！");
                    }
                    return;
                }

                #region 申请目标任务

                //前面都通过，则任务开始请求分配重复
                //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                //判断设备在wcs是否已存在分配巷道任务
                var exp = Expressionable.Create<WorkTaskInfo>();
                exp.AndIF(true, (a) => a.PalletCode == plcMessage.PalletBarcode && (a.TaskState == EnumTaskState.Initial || a.TaskState == EnumTaskState.Executing));
                var wcsWorkTaskInfo = await _workTaskInfoRepository.GetFirstAsync(exp.ToExpression());
                //根据托盘是否存在其它的任务 && 起点位置是否相同判断，存在则写入正常报文Return
                if (wcsWorkTaskInfo != null /*&& wcsWorkTaskInfo.CurrentFromEquipment == plcMessage.EquipmentCode*/)
                {
                    //runLogInfo.RunLog = $"请求分配重复:任务号：{wcsWorkTaskInfo.TaskCode}入库任务已存在";
                    //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);

                    _logUtil.Error($"绑盘机校验：托盘【{plcMessage.PalletBarcode}】任务号：{wcsWorkTaskInfo.TaskCode}任务已存在");
                    //针对wcs任务为初始化的处理成执行中并同步更新wms任务状态
                    if (wcsWorkTaskInfo.TaskState == EnumTaskState.Initial || wcsWorkTaskInfo.TaskState == EnumTaskState.Executing)
                    {
                        wcsWorkTaskInfo.TaskState = EnumTaskState.Executing;
                        wcsWorkTaskInfo.UpdateTime = DateTime.Now;
                        wcsWorkTaskInfo.CurrentDetailTaskState = EnumDetailTaskState.Executing;
                        try
                        {
                            //同步更新wms任务状态
                            var flag = await WCSMessageWithWMSApi.WCSUpdateWMStaskStateAndProcessTaskStateAsync(wcsWorkTaskInfo.WmsTaskCode, (int)EnumTaskState.Executing);
                            if (flag)
                            {
                                wcsWorkTaskInfo.UploadWmsState = EnumUploadWmsState.Succeed;
                                wcsWorkTaskInfo.UploadWmsTime = DateTime.Now;
                            }
                        }
                        catch (Exception ex)
                        {

                            //runLogInfo.RunLog = $"wms任务号{wcsWorkTaskInfo.TaskCode}同步状态更新失败";
                            //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                            _logUtil.Error($"绑盘机校验：托盘【{plcMessage.PalletBarcode}】同步状态更新报错：{ex.Message}");
                        }
                        //更新wcs任务状态为执行中
                        await _workTaskInfoRepository.UpdateAsync(wcsWorkTaskInfo);
                    }

                    //写入正常报文
                    writeBo.TaskCode = wcsWorkTaskInfo.TaskCode;
                    writeBo.PalletBarcode = wcsWorkTaskInfo.PalletCode;
                    writeBo.ToEquipmentCode = wcsWorkTaskInfo.CurrentToEquipment.ToInt32();
                    var writeBl = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());
                    if (!writeBl)
                    {
                        //runLogInfo.RunLog = $"请求分配重复:写入正常报文报文失败";
                        //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);

                        _logUtil.Error($"绑盘机校验：托盘【{plcMessage.PalletBarcode}】申请任务，PLC设备【{plcMessage.EquipmentCode}】写入PLC失败！");
                        return;
                    }
                    else
                    {
                        runLogInfo.RunLog = $"绑盘机校验：托盘【{plcMessage.PalletBarcode}】申请任务，PLC设备【{plcMessage.EquipmentCode}】写入PLC成功！写入报文：{JsonConvert.SerializeObject(writeBo)}";
                        await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);

                    }
                    return;
                }

                #region wcs托盘上架任务NA逻辑处理
                WmsTaskInfoDto workTaskDto = null;
                try
                {
                    //向wms读取巷道分配任务
                    WMSApiDomain.WebApi.HeaderResult<WmsTaskInfoDto> res = await WCSMessageWithWMSApi.WCSCreatUploadWarehouseWMSTaskAsync(plcMessage.PalletBarcode, plcMessage.EquipmentCode);
                    if (res.IsSucceed)
                    {
                        workTaskDto = res.Result;
                    }
                    else
                    {
                        var msg = res.Message;
                        runLogInfo.RunLog = $"向Wms请求任务失败:{msg}";
                        //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                        if (msg.Contains("没有配置工位信息"))
                            writeBo.AlrmCode = 20;
                        else if (msg.Contains("NG分选机出口扫码位置流程报错"))
                            writeBo.AlrmCode = 21;
                        else if (msg.Contains("不存在业务类型数据"))
                            writeBo.AlrmCode = 22;
                        else if (msg.Contains("扫码位置流程报错"))
                            writeBo.AlrmCode = 23;
                        else if (msg.Contains("投入口无法查询对应的流程"))
                            writeBo.AlrmCode = 24;
                        else if (msg.Contains("没有绑定流程参数"))
                            writeBo.AlrmCode = 25;
                        else if (msg.Contains("节点数据配置异常"))
                            writeBo.AlrmCode = 26;
                        else if (msg.Contains("未配置巷道分配关联数据"))
                            writeBo.AlrmCode = 27;
                        else if (msg.Contains("未配置巷道分配关联明细数据"))
                            writeBo.AlrmCode = 28;
                        else if (msg.Contains("未配置巷道分组指针"))
                            writeBo.AlrmCode = 29;
                        else if (msg.Contains("没有可用巷道"))
                            writeBo.AlrmCode = 30;
                        else if (msg.Contains("不存在流程配置参数数据"))
                            writeBo.AlrmCode = 43;
                        else if (msg.Contains("未解绑"))
                            writeBo.AlrmCode = 41;
                        else if (msg.Contains("不存在托盘数据"))
                            writeBo.AlrmCode = 44;
                        else if (msg.Contains("流程节点应为待处理状态！请查看OCV数据是否上传"))
                            writeBo.AlrmCode = 47;
                        else if (msg.Contains("请调整对应流程节点状态为待处理状态"))
                            writeBo.AlrmCode = 48;
                        else if (msg.Contains("绑定的流程配置有误！，OCV没测试排出"))
                            writeBo.AlrmCode = 49;
                        else if (msg.Contains("无法获取对应电池类型配置的流程参数"))
                            writeBo.AlrmCode = 50;
                        else if (msg.Contains("任务到达上限"))
                            writeBo.AlrmCode = 51;
                        else if (msg.Contains("没有上传数据"))
                            writeBo.AlrmCode = 52;
                        else
                            writeBo.AlrmCode = 105;
                        if (writeBo.AlrmCode == 0)
                            writeBo.AlrmCode = 3;

                        writeBo.ActionType = 99;
                        var flag = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());
                        _IRedisHelper.SetStringKey($"PLC-{plcMessage.EquipmentCode}", plcMessage.EquipmentCode.ToString() + plcMessage.AlrmCode, TimeSpan.FromSeconds(10));
                        _logUtil.Error($"绑盘机校验：托盘【{plcMessage.PalletBarcode}】在设备【{plcMessage.EquipmentCode}】请求分配失败：ex{runLogInfo.RunLog}");
                        return;
                    }
                }
                catch (Exception ex)
                {
                    if (ex.Message.Contains("at") && ex.Message.Contains("System.Exception:"))
                    {
                        var msg = ex.Message.Split("at").First().Split("System.Exception:");
                        runLogInfo.RunLog = $"向Wms请求任务失败:{msg[1]}";
                    }
                    else
                    {
                        var msg = ex.Message.Length > 150 ? ex.Message.Substring(0, 100) : ex.Message;
                        runLogInfo.RunLog = $"向Wms请求任务失败:{msg}";
                    }
                    writeBo.AlrmCode = 106;
                    writeBo.ActionType = 99;
                    var flag = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());
                    _IRedisHelper.SetStringKey($"PLC-{plcMessage.EquipmentCode}", plcMessage.EquipmentCode.ToString() + plcMessage.AlrmCode, TimeSpan.FromSeconds(10));
                    _logUtil.Error($"绑盘机校验：托盘【{plcMessage.PalletBarcode}】在设备【{plcMessage.EquipmentCode}】请求分配失败：ex{runLogInfo.RunLog}");
                    return;
                }

                //wms请求失败处理 写入100报警握手类型
                if (workTaskDto == null)
                {

                    runLogInfo.RunLog = $"向Wms请求任务失败WMS返回空";
                    writeBo.AlrmCode = 107;
                    writeBo.ActionType = 99;
                    var flag = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());
                    _IRedisHelper.SetStringKey($"PLC-{plcMessage.EquipmentCode}", plcMessage.EquipmentCode.ToString() + plcMessage.AlrmCode, TimeSpan.FromSeconds(10));
                    _logUtil.Error($"绑盘机校验：托盘【{plcMessage.PalletBarcode}】在设备【{plcMessage.EquipmentCode}】请求分配失败：ex{runLogInfo.RunLog}");
                    return;
                }

                //WorkTaskInfo数据补全
                var workTaskInfo = new WorkTaskInfo();

                long id = _snowflake.GetId();//雪花ID
                workTaskInfo.ID = id;
                //wcs任务code从wmstaskcode日开始截取
                int.TryParse(workTaskDto.TaskCode.ToString().Substring(6), out var wcsTaskCode);
                workTaskInfo.TaskCode = wcsTaskCode;
                //wms赋值
                workTaskInfo.WmsTaskCode = workTaskDto.TaskCode;
                workTaskInfo.DependWmsTaskCode = workTaskDto.DependWMSTaskCode;
                workTaskInfo.TaskType = Enum.Parse<EnumTaskType>(workTaskDto.TaskType.ToString());

                workTaskInfo.WmsFromPosition = workTaskDto.StartPosition;//WMS起始位置
                workTaskInfo.WmsToPosition = workTaskDto.EndPosition;//WMS目标位置
                workTaskInfo.WmsFromStation = workTaskDto.FromStation;//WMS起始工位
                workTaskInfo.WmsToStation = workTaskDto.ToStation;//WMS目标工位
                workTaskInfo.TaskProcessState = EnumTaskProcessState.Initial;
                workTaskInfo.TaskState = EnumTaskState.Executing;
                workTaskInfo.Priority = workTaskDto.Priority;

                //托盘条码
                workTaskInfo.PalletCode = plcMessage.PalletBarcode.Trim();

                #region 任务子任务信息赋值by RouteDetailInfo
                //获取配置巷道信息
                var routeConfigExp = Expressionable.Create<RouteInfo>();
                routeConfigExp.AndIF(true, (a) => a.FromStation == workTaskInfo.WmsFromStation && a.ToStation == workTaskInfo.WmsToStation);
                var routeInfo = await _workTaskInfoRepository.AsSugarClient()
                    .Queryable<RouteInfo>()
                    .Where(routeConfigExp.ToExpression())
                    .Select((a) => new RouteInfo()
                    {
                        ID = a.ID,
                        FromStation = a.FromStation,
                        ToStation = a.ToStation,
                    }).FirstAsync();
                if (routeInfo == null)
                {
                    runLogInfo.RunLog = $"起始工位{workTaskInfo.WmsFromStation}目标工位{workTaskInfo.WmsToStation}获取工位失败";
                    //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                    _logUtil.Error($"绑盘机校验：托盘【{plcMessage.PalletBarcode}】在设备【{plcMessage.EquipmentCode}】请求分配失败：ex{runLogInfo.RunLog}");
                    writeBo.AlrmCode = 108;
                    writeBo.ActionType = 99;
                    var flag = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());
                    _IRedisHelper.SetStringKey($"PLC-{plcMessage.EquipmentCode}", plcMessage.EquipmentCode.ToString() + plcMessage.AlrmCode, TimeSpan.FromSeconds(10));
                    return;
                }

                //巷道详情信息获取
                var routeDetailConfigExp = Expressionable.Create<RouteDetailInfo>();
                routeDetailConfigExp.AndIF(true, (a) => a.RouteID == routeInfo.ID && a.IsStart);
                var routeDetailInfo = await _workTaskInfoRepository.AsSugarClient()
                    .Queryable<RouteDetailInfo>()
                    .Where(routeDetailConfigExp.ToExpression())
                    .Select((a) => new
                    {
                        a.ID,
                        a.RouteID,
                        a.FromCargo,
                        a.ToCargo,
                        a.DispatchType,
                        a.FromEquipment,
                        a.ToEquipment,

                    }).FirstAsync();

                if (routeDetailInfo == null)
                {
                    runLogInfo.RunLog = $"巷道路径详情配置信息起始工位{workTaskInfo.WmsFromStation}目标工位{workTaskInfo.WmsToStation}获取设备路径失败";
                    //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                    _logUtil.Error($"绑盘机校验：托盘【{plcMessage.PalletBarcode}】在设备【{plcMessage.EquipmentCode}】请求分配失败：ex{runLogInfo.RunLog}");
                    writeBo.AlrmCode = 109;
                    writeBo.ActionType = 99;
                    var flag = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());
                    _IRedisHelper.SetStringKey($"PLC-{plcMessage.EquipmentCode}", plcMessage.EquipmentCode.ToString() + plcMessage.AlrmCode, TimeSpan.FromSeconds(10));
                    return;
                }

                workTaskInfo.CurrentToEquipment = routeDetailInfo.ToEquipment;


                workTaskInfo.CurrentFromCargo = routeDetailInfo.FromCargo;
                workTaskInfo.CurrentToCargo = routeDetailInfo.ToCargo;
                workTaskInfo.RouteID = routeDetailInfo.RouteID;
                workTaskInfo.CurrentRounteDetailID = routeDetailInfo.ID;
                workTaskInfo.CurrentDispatchType = routeDetailInfo.DispatchType;
                //起始设备位 
                workTaskInfo.CurrentFromEquipment = workTaskInfo.WmsFromPosition; //WMS 作业实际起点设备
                workTaskInfo.CurrentDetailTaskState = EnumDetailTaskState.Executing;
                workTaskInfo.CurrentCreateTime = DateTime.Now;
                workTaskInfo.CurrentUpdateTime = DateTime.Now;
                #endregion

                workTaskInfo.SaveTime = DateTime.Now;
                workTaskInfo.UpdateTime = DateTime.Now;

                #region 同步更新wms任务状态&写入正常报文
                //写入正常报文到Plc
                writeBo.TaskCode = workTaskInfo.TaskCode;//wcs任务号
                writeBo.ToEquipmentCode = workTaskInfo.CurrentToEquipment.ToInt32();//目标设备编号

                //runLogInfo.RunLog = $"PLC写入报文内容： {JsonConvert.SerializeObject(writeBo)}";
                //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                var writeResult = await plcConn.WriteDbAsync(writeBo.DbCode, writeBo.DbStart, writeBo.Deserialize());


                if (writeResult == false)
                {
                    runLogInfo.RunLog = $"绑盘机校验分配目标位写入报文失败";
                    //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                    _logUtil.Error($"绑盘机校验：托盘【{plcMessage.PalletBarcode}】在设备【{plcMessage.EquipmentCode}】请求分配：ex{runLogInfo.RunLog}");
                    return;
                }
                else
                {
                    runLogInfo.RunLog = $"绑盘机校验：托盘【{plcMessage.PalletBarcode}】在设备【{plcMessage.EquipmentCode}】分配目标位写入报文成功！PLC写入报文内容： {JsonConvert.SerializeObject(writeBo)}";
                    await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                }


                try
                {
                    //同步更新wms任务状态为执行中
                    var flag = await WCSMessageWithWMSApi.WCSUpdateWMStaskStateAndProcessTaskStateAsync(workTaskInfo.WmsTaskCode, (int)EnumTaskState.Executing);
                    if (flag)
                    {
                        workTaskInfo.UploadWmsState = EnumUploadWmsState.Succeed;
                        workTaskInfo.UploadWmsTime = DateTime.Now;
                    }
                    else
                    {
                        workTaskInfo.UploadWmsState = EnumUploadWmsState.Failed;
                        workTaskInfo.UploadWmsTime = DateTime.Now;
                    }
                    runLogInfo.RunLog = $"任务号{workTaskInfo.WmsTaskCode}:向Wms同步状态更新状态：{flag}";
                    _logUtil.Error($"绑盘机校验：托盘【{plcMessage.PalletBarcode}】在设备【{plcMessage.EquipmentCode}】同步WMS任务状态：ex{runLogInfo.RunLog}");
                }
                catch (Exception ex)
                {
                    runLogInfo.RunLog = $"任务号{workTaskInfo.WmsTaskCode}:向Wms同步状态更新失败，报错 ex={ex.Message}";

                    //await _IRunLogInfoService.AddRunLogInfoAsync(runLogInfo);
                    _logUtil.Error($"绑盘机校验：托盘【{plcMessage.PalletBarcode}】在设备【{plcMessage.EquipmentCode}】同步WMS任务状态：ex{runLogInfo.RunLog}");
                }

                //WorkTaskInfo数据插入
                var expCheck = Expressionable.Create<WorkTaskInfo>();
                expCheck.AndIF(true, (a) => a.PalletCode == plcMessage.PalletBarcode && (a.TaskState == EnumTaskState.Initial || a.TaskState == EnumTaskState.Executing));
                var wcsCheckWorkTaskInfo = await _workTaskInfoRepository.GetFirstAsync(expCheck.ToExpression());
                if (wcsCheckWorkTaskInfo == null)
                {
                    bool bl = await _workTaskInfoRepository.InsertAsync(workTaskInfo);
                }

                #endregion

                #endregion

                #endregion



            }


        }


        /// <summary>
        /// 电芯条码和位置处理
        /// </summary>
        /// <param name="batteryScanPlcAction"></param>
        /// <returns></returns>
        public List<WCSOneBatteryDto> GetBatteryDto(PlanarBatteryScanPlcActionBO batteryScanPlcAction)
        {
            List<WCSOneBatteryDto> oneBatteryInfoDtos = new()
            {
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 1,
                    BatteryCode = batteryScanPlcAction.BatteryCode1
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 2,
                    BatteryCode = batteryScanPlcAction.BatteryCode2
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 3,
                    BatteryCode = batteryScanPlcAction.BatteryCode3
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 4,
                    BatteryCode = batteryScanPlcAction.BatteryCode4
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 5,
                    BatteryCode = batteryScanPlcAction.BatteryCode5
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 6,
                    BatteryCode = batteryScanPlcAction.BatteryCode6
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 7,
                    BatteryCode = batteryScanPlcAction.BatteryCode7
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 8,
                    BatteryCode = batteryScanPlcAction.BatteryCode8
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 9,
                    BatteryCode = batteryScanPlcAction.BatteryCode9
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 10,
                    BatteryCode = batteryScanPlcAction.BatteryCode10
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 11,
                    BatteryCode = batteryScanPlcAction.BatteryCode11
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 12,
                    BatteryCode = batteryScanPlcAction.BatteryCode12
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 13,
                    BatteryCode = batteryScanPlcAction.BatteryCode13
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 14,
                    BatteryCode = batteryScanPlcAction.BatteryCode14
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 15,
                    BatteryCode = batteryScanPlcAction.BatteryCode15
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 16,
                    BatteryCode = batteryScanPlcAction.BatteryCode16
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 17,
                    BatteryCode = batteryScanPlcAction.BatteryCode17
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 18,
                    BatteryCode = batteryScanPlcAction.BatteryCode18
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 19,
                    BatteryCode = batteryScanPlcAction.BatteryCode19
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 20,
                    BatteryCode = batteryScanPlcAction.BatteryCode20
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 21,
                    BatteryCode = batteryScanPlcAction.BatteryCode21
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 22,
                    BatteryCode = batteryScanPlcAction.BatteryCode22
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 23,
                    BatteryCode = batteryScanPlcAction.BatteryCode23
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 24,
                    BatteryCode = batteryScanPlcAction.BatteryCode24
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 25,
                    BatteryCode = batteryScanPlcAction.BatteryCode25
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 26,
                    BatteryCode = batteryScanPlcAction.BatteryCode26
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 27,
                    BatteryCode = batteryScanPlcAction.BatteryCode27
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 28,
                    BatteryCode = batteryScanPlcAction.BatteryCode28
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 29,
                    BatteryCode = batteryScanPlcAction.BatteryCode29
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 30,
                    BatteryCode = batteryScanPlcAction.BatteryCode30
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 31,
                    BatteryCode = batteryScanPlcAction.BatteryCode31
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 32,
                    BatteryCode = batteryScanPlcAction.BatteryCode32
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 33,
                    BatteryCode = batteryScanPlcAction.BatteryCode33
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 34,
                    BatteryCode = batteryScanPlcAction.BatteryCode34
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 35,
                    BatteryCode = batteryScanPlcAction.BatteryCode35
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 36,
                    BatteryCode = batteryScanPlcAction.BatteryCode36
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 37,
                    BatteryCode = batteryScanPlcAction.BatteryCode37
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 38,
                    BatteryCode = batteryScanPlcAction.BatteryCode38
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 39,
                    BatteryCode = batteryScanPlcAction.BatteryCode39
                },
                new WCSOneBatteryDto()
                {
                    BatteryIndex = 40,
                    BatteryCode = batteryScanPlcAction.BatteryCode40
                }
            };

            return oneBatteryInfoDtos;
        }

    }
}
